package com.canal.display.service;

import com.alibaba.fastjson.JSONObject;
import com.canal.display.config.properties.CanalProperties;
import com.canal.display.dao.ZcolChannelMapper;
import com.canal.display.entity.canal.ZcolChannel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author Administrator
 * @description
 * @date 2019年03月17 11:03
 */
@Component
public class UserTokenService implements UserDetailsService {

    @Autowired
    private ZcolChannelMapper zcolChannelMapper;

    private RedisTemplate redisTemplate;

    @Autowired
    private CanalProperties canalProperties;

    public UserTokenService(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        ZcolChannel user = zcolChannelMapper.getChannelByName(username);
        return user;
    }

    /**
     * 保存用户到redis token中
     * @param user
     * @return
     */
    public String saveUserLoginInfo(UserDetails user) {
        String username = user.getUsername();
        Map<String, String> userMap = new HashMap<>(4);
        userMap.put("username",username);
        //设置token刷新时间，超过这个时间就刷新
        userMap.put("refreshTime",(System.currentTimeMillis()+canalProperties.getTokenExpire())+"");
        String jsonStr = JSONObject.toJSONString(userMap);
        String token = UUID.randomUUID().toString();
        setTokenToRedis(jsonStr, token);
        return token;
    }

    /**
     * 设置token到redis中
     * @param jsonStr
     * @param token
     */
    public void setTokenToRedis(String jsonStr, String token) {
        redisTemplate.opsForValue().set(token,jsonStr,1, TimeUnit.DAYS);
    }

    /**
     * 得到用户信息
     * @param token
     * @return
     */
    public UserDetails getUserLoginInfo(String token) {
        String tokenValue = (String) redisTemplate.opsForValue().get(token);
        if(StringUtils.isBlank(tokenValue)) {
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(tokenValue);
        String username = (String) jsonObject.get("username");
        // 这里其实可以将UserDetails缓存到redis中，这样可以减少数据库的访问
        UserDetails user = loadUserByUsername(username);
        return user;
    }

    /**
     * 查看token是否过期
     * @param token
     * @return
     */
    public boolean tokenIsNotExpired(String token) {
        return redisTemplate.hasKey(token);
    }

    /**
     * 获取刷新时间点,超过该时间就刷新token过期时间(过期时间由redis维护)
     * @param token
     * @return
     */
    public String refreshTime(String token) {
        String tokenValue = (String) redisTemplate.opsForValue().get(token);
        JSONObject jsonObject = JSONObject.parseObject(tokenValue);
        String refreshTime = (String) jsonObject.get("refreshTime");
        return refreshTime;
    }

    /**
     * 清除token
     * @param token
     */
    public void clearToken(String token) {
        redisTemplate.delete(token);
    }
}
